package com.hitqz.robot.biz.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.tree.Tree;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hitqz.robot.api.business.component.ExcelSelectedResolve;
import com.hitqz.robot.api.business.component.SelectedSheetWriteHandler;
import com.hitqz.robot.api.business.dto.PatrolContentExcelDto;
import com.hitqz.robot.biz.util.PatrolExcelFormworkDto;
import com.hitqz.robot.api.business.model.vo.patrol.PatrolPosPoseGroupVo;
import com.hitqz.robot.api.business.util.ExcelUtil;
import com.hitqz.robot.api.common.dto.file.UploadFileVo;
import com.hitqz.robot.api.common.entity.*;
import com.hitqz.robot.biz.core.FileProperties;
import com.hitqz.robot.biz.service.*;
import com.hitqz.robot.biz.util.PatrolObjectSelector;
import com.hitqz.robot.common.core.util.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author wengyx
 * @date 2024/8/7
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/patrolDev")
@Tag(name = "巡检设备管理")
public class PatrolDevController {

    private final PatrolDevService patrolDevService;

    private final PatrolPosPoseGroupService patrolPosPoseGroupService;

    private final PatrolPoseGroupService patrolPoseGroupService;

    private final PatrolItemService patrolItemService;

    private final FileProperties fileProperties;
    private final RobotMapPosService robotMapPosService;
    private final PatrolObjectService patrolObjectService;

    public record TreeRequest(String name){}

    @PostMapping("/tree")
    @Operation(summary = "获取巡检设备树")
    public R selectTree(@RequestBody(required = false) TreeRequest request ) {
        String name = request != null ? request.name() : null;
        List<Tree<Long>> trees = patrolDevService.selectTree(name);
        return R.ok(trees);
    }


    @GetMapping("/{id}/item")
    @Operation(summary = "根据id查询巡检设备下巡检项")
    public R<List<PatrolItem>> getItemListById(@PathVariable("id") Integer id) {
        List<PatrolPosPoseGroup> posPoseGroupList = patrolPosPoseGroupService.list(Wrappers.<PatrolPosPoseGroup>lambdaQuery().eq(PatrolPosPoseGroup::getDevId,id));
        List<PatrolItem> itemList = new ArrayList<>();
        for (PatrolPosPoseGroup posPoseGroup : CollUtil.emptyIfNull(posPoseGroupList)) {
            List<PatrolItem> list = patrolItemService.list(Wrappers.<PatrolItem>lambdaQuery().eq(PatrolItem::getPatrolPosPoseGroupId, posPoseGroup.getId()));
            itemList.addAll(list);
        }
        return R.ok(itemList);
    }


    @GetMapping("/{id}" )
    @Operation(summary = "根据id查询巡检设备")
    public R<PatrolDev> getById(@PathVariable("id") Integer id) {
        PatrolDev patrolDev = patrolDevService.getById(id);
        return R.ok(patrolDev);
    }

    @GetMapping("/{id}/posPoseGroup" )
    @Operation(summary = "根据id查询巡检设备底下位置姿态组关系")
    public R<List<PatrolPosPoseGroupVo>> getPosPoseGroupListById(@PathVariable("id") Integer id) {
        List<PatrolPosPoseGroupVo> voList = patrolPosPoseGroupService.getVoListByDevId(id);
        return R.ok(voList);
    }



    @PostMapping
    @Operation(summary = "新增巡检设备")
    public R save(@RequestBody @Validated PatrolDev dto) {
        return R.ok(patrolDevService.save(dto));
    }

    @PutMapping
    @Operation(summary = "修改巡检设备")
    public R updateById(@RequestBody @Validated PatrolDev dto) {
        return R.ok(patrolDevService.updateById(dto));
    }

    @DeleteMapping
    @Operation(summary = "根据id删除巡检设备")
    public R removeById(@RequestBody Integer[] ids) {
        return R.ok(patrolDevService.removeBatchByIds(CollUtil.toList(ids)));
    }

    //下载模板
    @GetMapping("/excel/formwork")
    @Operation(summary = "下载模版")
    public void export(HttpServletResponse response) throws IOException {
        List<PatrolObject> list = patrolObjectService.list();
        if (list.isEmpty()){
            ExcelUtil.response2Web(response,"无巡检对象,请先添加");
            return;
        }
        String formwork = ExcelUtil.getPatrolExcelFilePath(fileProperties.getLocal().getBasePath(), 0);
        Map<Integer, ExcelSelectedResolve> resolveMap = ExcelUtil.resolveSelectedAnnotation(PatrolExcelFormworkDto.class);
        EasyExcel.write(formwork, PatrolExcelFormworkDto.class)
                .sheet("Sheet1")
                .registerWriteHandler(new SelectedSheetWriteHandler(resolveMap))
                // 当然这里数据也可以用 List<List<String>> 去传入
                .doWrite(new ArrayList<>());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //给前端返回文件
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("检测项模版", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(FileUtil.readBytes(formwork));
        outputStream.close();
    }



    //fixme  导入Excel数据
    @PostMapping("/excel/upload")
    @Operation(summary = "excel导入巡检配置")
    public R uploadExcel(@RequestBody UploadFileVo uploadFile) {
        String filePath = uploadFile.getFilePath();
        File excelFile = new File(fileProperties.getLocal().getBasePath() + filePath);
        if (!excelFile.exists()){
            return R.failed("上传文件失败");
        }

        ArrayList<PatrolContentExcelDto> list = new ArrayList<>();
        EasyExcel.read(excelFile, PatrolContentExcelDto.class, new PageReadListener<PatrolContentExcelDto>(dataList -> {
            for (PatrolContentExcelDto demoData : dataList) {
                log.info("读取到一条数据{}", JSON.toJSONString(demoData));
                list.add(demoData);
            }
        })).sheet().doRead();
        for (PatrolContentExcelDto dto : list) {
            String roomName = dto.getRoomName();
            String devName = dto.getDevName();
            String itemName = dto.getItemName();
            PatrolDev room = patrolDevService.getOne(Wrappers.<PatrolDev>lambdaQuery().eq(PatrolDev::getName, roomName).eq(PatrolDev::getIsParent, 1).last("limit 1"));
            if (room == null) {
                room = new PatrolDev();
                room.setIsParent(1);
                room.setParentId(0);
                room.setName(roomName);
                log.info("save room {},{},{}", patrolDevService.save(room), room.getId(), room);
            }
            PatrolDev dev = patrolDevService.getOne(Wrappers.<PatrolDev>lambdaQuery().eq(PatrolDev::getName, devName).eq(PatrolDev::getParentId, room.getId()).last("limit 1"));
            if (dev == null) {
                dev = new PatrolDev();
                dev.setParentId(room.getId().intValue());
                dev.setName(devName);
                dev.setIsParent(0);
                log.info("save dev:{},{},{}", patrolDevService.save(dev), dev.getId(), dev);
            }
            PatrolPoseGroup patrolPoseGroup = patrolPoseGroupService.getOne(Wrappers.<PatrolPoseGroup>lambdaQuery().eq(PatrolPoseGroup::getName, itemName).last("limit 1"));
            if (patrolPoseGroup == null) {
                patrolPoseGroup = new PatrolPoseGroup();
                patrolPoseGroup.setName(itemName);
                log.info("save patrolPoseGroup:{},{},{}", patrolPoseGroupService.save(patrolPoseGroup), patrolPoseGroup.getId(), patrolPoseGroup);
            }
            PatrolPosPoseGroup posPoseGroup = patrolPosPoseGroupService.getOne(Wrappers.<PatrolPosPoseGroup>lambdaQuery().eq(PatrolPosPoseGroup::getDevId, dev.getId())
                    .eq(PatrolPosPoseGroup::getPatrolPoseGroupId, patrolPoseGroup.getId()).last("limit 1"));
            if (posPoseGroup == null) {
                posPoseGroup = new PatrolPosPoseGroup();
                posPoseGroup.setDevId(dev.getId().intValue());
                posPoseGroup.setPatrolPoseGroupId(patrolPoseGroup.getId().intValue());
                //点位随便设置一个
                RobotMapPos pos = robotMapPosService.getOne(Wrappers.<RobotMapPos>lambdaQuery().eq(RobotMapPos::getCode, "1").last("limit 1"));
                int posId = pos.getId().intValue();
//                List<PatrolPosPoseGroup> list1 = patrolPosPoseGroupService.list(Wrappers.<PatrolPosPoseGroup>lambdaQuery().eq(PatrolPosPoseGroup::getDevId, dev.getId()));
//                for (PatrolPosPoseGroup patrolPosPoseGroup : list1) {
//                    PatrolItem patrolItem = patrolItemService.getOne(Wrappers.<PatrolItem>lambdaQuery().eq(PatrolItem::getPatrolPosPoseGroupId, patrolPosPoseGroup.getId()).like(PatrolItem::getName, "鹤管").last("limit 1"));
//                    if (patrolItem != null){
//                        posId = patrolPosPoseGroup.getPosId();
//                        break;
//                    }
//                }
                posPoseGroup.setPosId(posId);
                posPoseGroup.setIsBack(0);
                posPoseGroup.setIsDynamic(0);
                posPoseGroup.setIsLight(0);
                log.info("save posPoseGroup:{},{},{}", patrolPosPoseGroupService.save(posPoseGroup), posPoseGroup.getId(), posPoseGroup);
            }
            List<PatrolObject> objectList = patrolObjectService.list();
            PatrolItem patrolItem = patrolItemService.getOne(Wrappers.<PatrolItem>lambdaQuery().eq(PatrolItem::getPatrolPosPoseGroupId, posPoseGroup.getId())
                    .eq(PatrolItem::getName, itemName).last("limit 1"));
            if (patrolItem == null) {
                patrolItem = new PatrolItem();
                patrolItem.setName(itemName);
                patrolItem.setPatrolPosPoseGroupId(posPoseGroup.getId().intValue());
                patrolItem.setEquipmentId(2);
                //默认的
                if (!objectList.isEmpty()){
                    patrolItem.setPatrolObjectId(objectList.get(0).getId().intValue());
                }
                //实际的
                try {
                    String s = dto.getObjectName().split("_")[0];
                    patrolItem.setPatrolObjectId(Integer.valueOf(s));
                }catch (Exception e){
                    log.error("解析失败:{}",dto.getObjectName());
                }
                log.info("save item:{},{},{}", patrolItemService.save(patrolItem), patrolItem.getId(), patrolItem);
            }
            //log.info("dto:{}",dto);
        }

        return R.ok();
    }






}
